import jdk.internal.org.objectweb.asm.signature.SignatureReader;
import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class ser {
    @Test
    public void client() throws IOException {
//        建立一个客户端通道
        SocketChannel clchannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9898));
//        改变阻塞方式
        clchannel.configureBlocking(false);
//        分配缓冲区
        ByteBuffer clientbuffer = ByteBuffer.allocate(1024);
//        往缓冲区中存入信息
        clientbuffer.put(new Date().toString().getBytes());
//        改变缓冲区读写模式
        clientbuffer.flip();
//        又通道进行操作缓冲区
        clchannel.write(clientbuffer);
        clientbuffer.clear();
        clchannel.close();
    }

    @Test
    public void service() throws IOException {
//        创建服务端通道
        ServerSocketChannel serchannel = ServerSocketChannel.open();
//        修改通道阻塞方式
        serchannel.configureBlocking(false);
//        绑定连接
        serchannel.bind(new InetSocketAddress(9898));
//        创建选择器
        Selector selector = Selector.open();
//        将服务端通道绑定选择器，用来监视该通道的状态
        serchannel.register(selector, SelectionKey.OP_ACCEPT);
//        使用while轮询方式判断selector中的状态数量
        while (selector.select()>0){
//            使用迭代器迭代选择键
            Iterator<SelectionKey> selectionKeyIterator=selector.selectedKeys().iterator();
//            轮询已经存在了的选择键
            while (selectionKeyIterator.hasNext()){
//                获取纯在的选择键
                SelectionKey key = selectionKeyIterator.next();
//                判断状态
                if (key.isAcceptable()){
//                    接收就绪，获取客户端通道SocketChannel
                    SocketChannel clchannel = serchannel.accept();
                    clchannel.configureBlocking(false);
//                    监听该通道的读就绪状态
                    clchannel.register(selector,SelectionKey.OP_READ);
                }else if (key.isReadable()){
//                    获取读就绪状态的通道
                    SocketChannel nextch = (SocketChannel) key.channel();
//                    分配缓冲空间
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int len=0;
//                    使用len接收数据，len>0说明有数据
                    while ((len=nextch.read(buffer))>0){
                        buffer.flip();
                        System.out.println(new String(buffer.array(),0,len));
                        buffer.clear();
                    }
                    }
                selectionKeyIterator.remove();
                }
            }
        }

}
